{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "executionInfo": {
     "elapsed": 4,
     "status": "ok",
     "timestamp": 1649954990831,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "FsUgv8sL-tZ4"
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from tqdm import tqdm  # tqdm是显示循环进度条的库\n",
    "\n",
    "\n",
    "class CliffWalkingEnv:\n",
    "    def __init__(self, ncol, nrow):\n",
    "        self.nrow = nrow\n",
    "        self.ncol = ncol\n",
    "        self.x = 0  # 记录当前智能体位置的横坐标\n",
    "        self.y = self.nrow - 1  # 记录当前智能体位置的纵坐标\n",
    "\n",
    "    def step(self, action):  # 外部调用这个函数来改变当前位置\n",
    "        # 4种动作, change[0]:上, change[1]:下, change[2]:左, change[3]:右。坐标系原点(0,0)\n",
    "        # 定义在左上角\n",
    "        change = [[0, -1], [0, 1], [-1, 0], [1, 0]]\n",
    "        self.x = min(self.ncol - 1, max(0, self.x + change[action][0]))\n",
    "        self.y = min(self.nrow - 1, max(0, self.y + change[action][1]))\n",
    "        next_state = self.y * self.ncol + self.x\n",
    "        reward = -1\n",
    "        done = False\n",
    "        if self.y == self.nrow - 1 and self.x > 0:  # 下一个位置在悬崖或者目标\n",
    "            done = True\n",
    "            if self.x != self.ncol - 1:\n",
    "                reward = -100\n",
    "        return next_state, reward, done\n",
    "\n",
    "    def reset(self):  # 回归初始状态,坐标轴原点在左上角\n",
    "        self.x = 0\n",
    "        self.y = self.nrow - 1\n",
    "        return self.y * self.ncol + self.x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "executionInfo": {
     "elapsed": 428,
     "status": "ok",
     "timestamp": 1649954991256,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "BtsnlukF-tZ8"
   },
   "outputs": [],
   "source": [
    "class Sarsa:\n",
    "    \"\"\" Sarsa算法 \"\"\"\n",
    "    def __init__(self, ncol, nrow, epsilon, alpha, gamma, n_action=4):\n",
    "        self.Q_table = np.zeros([nrow * ncol, n_action])  # 初始化Q(s,a)表格\n",
    "        self.n_action = n_action  # 动作个数\n",
    "        self.alpha = alpha  # 学习率\n",
    "        self.gamma = gamma  # 折扣因子\n",
    "        self.epsilon = epsilon  # epsilon-贪婪策略中的参数\n",
    "\n",
    "    def take_action(self, state):  # 选取下一步的操作,具体实现为epsilon-贪婪\n",
    "        if np.random.random() < self.epsilon:\n",
    "            action = np.random.randint(self.n_action)\n",
    "        else:\n",
    "            action = np.argmax(self.Q_table[state])\n",
    "        return action\n",
    "\n",
    "    def best_action(self, state):  # 用于打印策略\n",
    "        Q_max = np.max(self.Q_table[state])\n",
    "        a = [0 for _ in range(self.n_action)]\n",
    "        for i in range(self.n_action):  # 若两个动作的价值一样,都会记录下来\n",
    "            if self.Q_table[state, i] == Q_max:\n",
    "                a[i] = 1\n",
    "        return a\n",
    "\n",
    "    def update(self, s0, a0, r, s1, a1):\n",
    "        td_error = r + self.gamma * self.Q_table[s1, a1] - self.Q_table[s0, a0]\n",
    "        self.Q_table[s0, a0] += self.alpha * td_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 469
    },
    "executionInfo": {
     "elapsed": 940,
     "status": "ok",
     "timestamp": 1649954992180,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "VzvRu8KZ-tZ9",
    "outputId": "22cd31df-9cdd-4a2c-83d5-cfccc320a9f0"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 748.17it/s, episode=50, return=-119.400]\n",
      "Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 929.51it/s, episode=100, return=-63.000]\n",
      "Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 902.21it/s, episode=150, return=-51.200]\n",
      "Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 565.54it/s, episode=200, return=-48.100]\n",
      "Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 865.24it/s, episode=250, return=-35.700]\n",
      "Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 1049.89it/s, episode=300, return=-29.900]\n",
      "Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 872.22it/s, episode=350, return=-28.300] \n",
      "Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 926.87it/s, episode=400, return=-27.700] \n",
      "Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 855.09it/s, episode=450, return=-28.500]\n",
      "Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 988.76it/s, episode=500, return=-18.900] \n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ncol = 12\n",
    "nrow = 4\n",
    "env = CliffWalkingEnv(ncol, nrow)\n",
    "np.random.seed(0)\n",
    "epsilon = 0.1\n",
    "alpha = 0.1\n",
    "gamma = 0.9\n",
    "agent = Sarsa(ncol, nrow, epsilon, alpha, gamma)\n",
    "num_episodes = 500  # 智能体在环境中运行的序列的数量\n",
    "\n",
    "return_list = []  # 记录每一条序列的回报\n",
    "for i in range(10):  # 显示10个进度条\n",
    "    # tqdm的进度条功能\n",
    "    with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:\n",
    "        for i_episode in range(int(num_episodes / 10)):  # 每个进度条的序列数\n",
    "            episode_return = 0\n",
    "            state = env.reset()\n",
    "            action = agent.take_action(state)\n",
    "            done = False\n",
    "            while not done:\n",
    "                next_state, reward, done = env.step(action)\n",
    "                next_action = agent.take_action(next_state)\n",
    "                episode_return += reward  # 这里回报的计算不进行折扣因子衰减\n",
    "                agent.update(state, action, reward, next_state, next_action)\n",
    "                state = next_state\n",
    "                action = next_action\n",
    "            return_list.append(episode_return)\n",
    "            if (i_episode + 1) % 10 == 0:  # 每10条序列打印一下这10条序列的平均回报\n",
    "                pbar.set_postfix({\n",
    "                    'episode':\n",
    "                    '%d' % (num_episodes / 10 * i + i_episode + 1),\n",
    "                    'return':\n",
    "                    '%.3f' % np.mean(return_list[-10:])\n",
    "                })\n",
    "            pbar.update(1)\n",
    "\n",
    "episodes_list = list(range(len(return_list)))\n",
    "plt.plot(episodes_list, return_list)\n",
    "plt.xlabel('Episodes')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('Sarsa on {}'.format('Cliff Walking'))\n",
    "plt.show()\n",
    "\n",
    "# Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 1206.19it/s, episode=50,\n",
    "# return=-119.400]\n",
    "# Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 1379.84it/s, episode=100,\n",
    "# return=-63.000]\n",
    "# Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 2225.14it/s, episode=150,\n",
    "# return=-51.200]\n",
    "# Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 2786.80it/s, episode=200,\n",
    "# return=-48.100]\n",
    "# Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 1705.21it/s, episode=250,\n",
    "# return=-35.700]\n",
    "# Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 3393.12it/s, episode=300,\n",
    "# return=-29.900]\n",
    "# Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 3694.32it/s, episode=350,\n",
    "# return=-28.300]\n",
    "# Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 3705.87it/s, episode=400,\n",
    "# return=-27.700]\n",
    "# Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 4115.61it/s, episode=450,\n",
    "# return=-28.500]\n",
    "# Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 3423.20it/s, episode=500,\n",
    "# return=-18.900]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 3,
     "status": "ok",
     "timestamp": 1649954992624,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "pDQX_Nrw-tZ_",
    "outputId": "f6139e63-8251-4731-8110-31492a83c86f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sarsa算法最终收敛得到的策略为：\n",
      "ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo \n",
      "ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo \n",
      "^ooo ooo> ^ooo ooo> ooo> ooo> ooo> ^ooo ^ooo ooo> ooo> ovoo \n",
      "^ooo **** **** **** **** **** **** **** **** **** **** EEEE \n"
     ]
    }
   ],
   "source": [
    "def print_agent(agent, env, action_meaning, disaster=[], end=[]):\n",
    "    for i in range(env.nrow):\n",
    "        for j in range(env.ncol):\n",
    "            if (i * env.ncol + j) in disaster:\n",
    "                print('****', end=' ')\n",
    "            elif (i * env.ncol + j) in end:\n",
    "                print('EEEE', end=' ')\n",
    "            else:\n",
    "                a = agent.best_action(i * env.ncol + j)\n",
    "                pi_str = ''\n",
    "                for k in range(len(action_meaning)):\n",
    "                    pi_str += action_meaning[k] if a[k] > 0 else 'o'\n",
    "                print(pi_str, end=' ')\n",
    "        print()\n",
    "\n",
    "\n",
    "action_meaning = ['^', 'v', '<', '>']\n",
    "print('Sarsa算法最终收敛得到的策略为：')\n",
    "print_agent(agent, env, action_meaning, list(range(37, 47)), [47])\n",
    "\n",
    "# Sarsa算法最终收敛得到的策略为：\n",
    "# ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo\n",
    "# ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo\n",
    "# ^ooo ooo> ^ooo ooo> ooo> ooo> ooo> ^ooo ^ooo ooo> ooo> ovoo\n",
    "# ^ooo **** **** **** **** **** **** **** **** **** **** EEEE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 469
    },
    "executionInfo": {
     "elapsed": 1302,
     "status": "ok",
     "timestamp": 1649954995824,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "0ZzmFvbA-tZ_",
    "outputId": "ee855cdd-16db-425c-8dd7-71d23aa182a6"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 790.85it/s, episode=50, return=-26.500]\n",
      "Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 1366.35it/s, episode=100, return=-35.200]\n",
      "Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 1457.31it/s, episode=150, return=-20.100]\n",
      "Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 869.99it/s, episode=200, return=-27.200] \n",
      "Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 713.46it/s, episode=250, return=-19.300]\n",
      "Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 841.88it/s, episode=300, return=-27.400]\n",
      "Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 792.21it/s, episode=350, return=-28.000]\n",
      "Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 1135.73it/s, episode=400, return=-36.500]\n",
      "Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 624.91it/s, episode=450, return=-27.000]\n",
      "Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 1092.57it/s, episode=500, return=-19.100]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "class nstep_Sarsa:\n",
    "    \"\"\" n步Sarsa算法 \"\"\"\n",
    "    def __init__(self, n, ncol, nrow, epsilon, alpha, gamma, n_action=4):\n",
    "        self.Q_table = np.zeros([nrow * ncol, n_action])\n",
    "        self.n_action = n_action\n",
    "        self.alpha = alpha\n",
    "        self.gamma = gamma\n",
    "        self.epsilon = epsilon\n",
    "        self.n = n  # 采用n步Sarsa算法\n",
    "        self.state_list = []  # 保存之前的状态\n",
    "        self.action_list = []  # 保存之前的动作\n",
    "        self.reward_list = []  # 保存之前的奖励\n",
    "\n",
    "    def take_action(self, state):\n",
    "        if np.random.random() < self.epsilon:\n",
    "            action = np.random.randint(self.n_action)\n",
    "        else:\n",
    "            action = np.argmax(self.Q_table[state])\n",
    "        return action\n",
    "\n",
    "    def best_action(self, state):  # 用于打印策略\n",
    "        Q_max = np.max(self.Q_table[state])\n",
    "        a = [0 for _ in range(self.n_action)]\n",
    "        for i in range(self.n_action):\n",
    "            if self.Q_table[state, i] == Q_max:\n",
    "                a[i] = 1\n",
    "        return a\n",
    "\n",
    "    def update(self, s0, a0, r, s1, a1, done):\n",
    "        self.state_list.append(s0)\n",
    "        self.action_list.append(a0)\n",
    "        self.reward_list.append(r)\n",
    "        if len(self.state_list) == self.n:  # 若保存的数据可以进行n步更新\n",
    "            G = self.Q_table[s1, a1]  # 得到Q(s_{t+n}, a_{t+n})\n",
    "            for i in reversed(range(self.n)):\n",
    "                G = self.gamma * G + self.reward_list[i]  # 不断向前计算每一步的回报\n",
    "                # 如果到达终止状态,最后几步虽然长度不够n步,也将其进行更新\n",
    "                if done and i > 0:\n",
    "                    s = self.state_list[i]\n",
    "                    a = self.action_list[i]\n",
    "                    self.Q_table[s, a] += self.alpha * (G - self.Q_table[s, a])\n",
    "            s = self.state_list.pop(0)  # 将需要更新的状态动作从列表中删除,下次不必更新\n",
    "            a = self.action_list.pop(0)\n",
    "            self.reward_list.pop(0)\n",
    "            # n步Sarsa的主要更新步骤\n",
    "            self.Q_table[s, a] += self.alpha * (G - self.Q_table[s, a])\n",
    "        if done:  # 如果到达终止状态,即将开始下一条序列,则将列表全清空\n",
    "            self.state_list = []\n",
    "            self.action_list = []\n",
    "            self.reward_list = []\n",
    "\n",
    "\n",
    "np.random.seed(0)\n",
    "n_step = 5  # 5步Sarsa算法\n",
    "alpha = 0.1\n",
    "epsilon = 0.1\n",
    "gamma = 0.9\n",
    "agent = nstep_Sarsa(n_step, ncol, nrow, epsilon, alpha, gamma)\n",
    "num_episodes = 500  # 智能体在环境中运行的序列的数量\n",
    "\n",
    "return_list = []  # 记录每一条序列的回报\n",
    "for i in range(10):  # 显示10个进度条\n",
    "    #tqdm的进度条功能\n",
    "    with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:\n",
    "        for i_episode in range(int(num_episodes / 10)):  # 每个进度条的序列数\n",
    "            episode_return = 0\n",
    "            state = env.reset()\n",
    "            action = agent.take_action(state)\n",
    "            done = False\n",
    "            while not done:\n",
    "                next_state, reward, done = env.step(action)\n",
    "                next_action = agent.take_action(next_state)\n",
    "                episode_return += reward  # 这里回报的计算不进行折扣因子衰减\n",
    "                agent.update(state, action, reward, next_state, next_action,\n",
    "                             done)\n",
    "                state = next_state\n",
    "                action = next_action\n",
    "            return_list.append(episode_return)\n",
    "            if (i_episode + 1) % 10 == 0:  # 每10条序列打印一下这10条序列的平均回报\n",
    "                pbar.set_postfix({\n",
    "                    'episode':\n",
    "                    '%d' % (num_episodes / 10 * i + i_episode + 1),\n",
    "                    'return':\n",
    "                    '%.3f' % np.mean(return_list[-10:])\n",
    "                })\n",
    "            pbar.update(1)\n",
    "\n",
    "episodes_list = list(range(len(return_list)))\n",
    "plt.plot(episodes_list, return_list)\n",
    "plt.xlabel('Episodes')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('5-step Sarsa on {}'.format('Cliff Walking'))\n",
    "plt.show()\n",
    "\n",
    "# Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 937.03it/s, episode=50,\n",
    "# return=-26.500]\n",
    "# Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 2955.94it/s, episode=100,\n",
    "# return=-35.200]\n",
    "# Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 2978.95it/s, episode=150,\n",
    "# return=-20.100]\n",
    "# Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 3062.61it/s, episode=200,\n",
    "# return=-27.200]\n",
    "# Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 3172.36it/s, episode=250,\n",
    "# return=-19.300]\n",
    "# Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 3123.41it/s, episode=300,\n",
    "# return=-27.400]\n",
    "# Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 2875.33it/s, episode=350,\n",
    "# return=-28.000]\n",
    "# Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 2262.18it/s, episode=400,\n",
    "# return=-36.500]\n",
    "# Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 3100.00it/s, episode=450,\n",
    "# return=-27.000]\n",
    "# Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 3107.54it/s, episode=500,\n",
    "# return=-19.100]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 541,
     "status": "ok",
     "timestamp": 1649954998993,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "EAxG4OS6-taA",
    "outputId": "f7187b7a-de76-496e-8225-9bbf1ac445f7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5步Sarsa算法最终收敛得到的策略为：\n",
      "ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo \n",
      "^ooo ^ooo ^ooo oo<o ^ooo ^ooo ^ooo ^ooo ooo> ooo> ^ooo ovoo \n",
      "ooo> ^ooo ^ooo ^ooo ^ooo ^ooo ^ooo ooo> ooo> ^ooo ooo> ovoo \n",
      "^ooo **** **** **** **** **** **** **** **** **** **** EEEE \n"
     ]
    }
   ],
   "source": [
    "action_meaning = ['^', 'v', '<', '>']\n",
    "print('5步Sarsa算法最终收敛得到的策略为：')\n",
    "print_agent(agent, env, action_meaning, list(range(37, 47)), [47])\n",
    "\n",
    "# 5步Sarsa算法最终收敛得到的策略为：\n",
    "# ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo\n",
    "# ^ooo ^ooo ^ooo oo<o ^ooo ^ooo ^ooo ^ooo ooo> ooo> ^ooo ovoo\n",
    "# ooo> ^ooo ^ooo ^ooo ^ooo ^ooo ^ooo ooo> ooo> ^ooo ooo> ovoo\n",
    "# ^ooo **** **** **** **** **** **** **** **** **** **** EEEE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 555
    },
    "executionInfo": {
     "elapsed": 1764,
     "status": "ok",
     "timestamp": 1649955002573,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "jgg5kRgg-taB",
    "outputId": "ec4a5456-d8cc-46ff-d127-54bd4e16e156"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 648.07it/s, episode=50, return=-105.700]\n",
      "Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 376.42it/s, episode=100, return=-70.900]\n",
      "Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 457.03it/s, episode=150, return=-56.500]\n",
      "Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 444.18it/s, episode=200, return=-46.500]\n",
      "Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 775.41it/s, episode=250, return=-40.800]\n",
      "Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 1067.26it/s, episode=300, return=-20.400]\n",
      "Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 1053.36it/s, episode=350, return=-45.700]\n",
      "Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 650.74it/s, episode=400, return=-32.800] \n",
      "Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 680.47it/s, episode=450, return=-22.700]\n",
      "Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 1112.17it/s, episode=500, return=-61.700]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Q-learning算法最终收敛得到的策略为：\n",
      "^ooo ovoo ovoo ^ooo ^ooo ovoo ooo> ^ooo ^ooo ooo> ooo> ovoo \n",
      "ooo> ooo> ooo> ooo> ooo> ooo> ^ooo ooo> ooo> ooo> ooo> ovoo \n",
      "ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo \n",
      "^ooo **** **** **** **** **** **** **** **** **** **** EEEE \n"
     ]
    }
   ],
   "source": [
    "class QLearning:\n",
    "    \"\"\" Q-learning算法 \"\"\"\n",
    "    def __init__(self, ncol, nrow, epsilon, alpha, gamma, n_action=4):\n",
    "        self.Q_table = np.zeros([nrow * ncol, n_action])  # 初始化Q(s,a)表格\n",
    "        self.n_action = n_action  # 动作个数\n",
    "        self.alpha = alpha  # 学习率\n",
    "        self.gamma = gamma  # 折扣因子\n",
    "        self.epsilon = epsilon  # epsilon-贪婪策略中的参数\n",
    "\n",
    "    def take_action(self, state):  #选取下一步的操作\n",
    "        if np.random.random() < self.epsilon:\n",
    "            action = np.random.randint(self.n_action)\n",
    "        else:\n",
    "            action = np.argmax(self.Q_table[state])\n",
    "        return action\n",
    "\n",
    "    def best_action(self, state):  # 用于打印策略\n",
    "        Q_max = np.max(self.Q_table[state])\n",
    "        a = [0 for _ in range(self.n_action)]\n",
    "        for i in range(self.n_action):\n",
    "            if self.Q_table[state, i] == Q_max:\n",
    "                a[i] = 1\n",
    "        return a\n",
    "\n",
    "    def update(self, s0, a0, r, s1):\n",
    "        td_error = r + self.gamma * self.Q_table[s1].max(\n",
    "        ) - self.Q_table[s0, a0]\n",
    "        self.Q_table[s0, a0] += self.alpha * td_error\n",
    "\n",
    "\n",
    "np.random.seed(0)\n",
    "epsilon = 0.1\n",
    "alpha = 0.1\n",
    "gamma = 0.9\n",
    "agent = QLearning(ncol, nrow, epsilon, alpha, gamma)\n",
    "num_episodes = 500  # 智能体在环境中运行的序列的数量\n",
    "\n",
    "return_list = []  # 记录每一条序列的回报\n",
    "for i in range(10):  # 显示10个进度条\n",
    "    # tqdm的进度条功能\n",
    "    with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:\n",
    "        for i_episode in range(int(num_episodes / 10)):  # 每个进度条的序列数\n",
    "            episode_return = 0\n",
    "            state = env.reset()\n",
    "            done = False\n",
    "            while not done:\n",
    "                action = agent.take_action(state)\n",
    "                next_state, reward, done = env.step(action)\n",
    "                episode_return += reward  # 这里回报的计算不进行折扣因子衰减\n",
    "                agent.update(state, action, reward, next_state)\n",
    "                state = next_state\n",
    "            return_list.append(episode_return)\n",
    "            if (i_episode + 1) % 10 == 0:  # 每10条序列打印一下这10条序列的平均回报\n",
    "                pbar.set_postfix({\n",
    "                    'episode':\n",
    "                    '%d' % (num_episodes / 10 * i + i_episode + 1),\n",
    "                    'return':\n",
    "                    '%.3f' % np.mean(return_list[-10:])\n",
    "                })\n",
    "            pbar.update(1)\n",
    "\n",
    "episodes_list = list(range(len(return_list)))\n",
    "plt.plot(episodes_list, return_list)\n",
    "plt.xlabel('Episodes')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('Q-learning on {}'.format('Cliff Walking'))\n",
    "plt.show()\n",
    "\n",
    "action_meaning = ['^', 'v', '<', '>']\n",
    "print('Q-learning算法最终收敛得到的策略为：')\n",
    "print_agent(agent, env, action_meaning, list(range(37, 47)), [47])\n",
    "\n",
    "# Iteration 0: 100%|██████████| 50/50 [00:00<00:00, 1183.69it/s, episode=50,\n",
    "# return=-105.700]\n",
    "# Iteration 1: 100%|██████████| 50/50 [00:00<00:00, 1358.13it/s, episode=100,\n",
    "# return=-70.900]\n",
    "# Iteration 2: 100%|██████████| 50/50 [00:00<00:00, 1433.72it/s, episode=150,\n",
    "# return=-56.500]\n",
    "# Iteration 3: 100%|██████████| 50/50 [00:00<00:00, 2607.78it/s, episode=200,\n",
    "# return=-46.500]\n",
    "# Iteration 4: 100%|██████████| 50/50 [00:00<00:00, 3007.19it/s, episode=250,\n",
    "# return=-40.800]\n",
    "# Iteration 5: 100%|██████████| 50/50 [00:00<00:00, 2005.77it/s, episode=300,\n",
    "# return=-20.400]\n",
    "# Iteration 6: 100%|██████████| 50/50 [00:00<00:00, 2072.14it/s, episode=350,\n",
    "# return=-45.700]\n",
    "# Iteration 7: 100%|██████████| 50/50 [00:00<00:00, 4244.04it/s, episode=400,\n",
    "# return=-32.800]\n",
    "# Iteration 8: 100%|██████████| 50/50 [00:00<00:00, 4670.82it/s, episode=450,\n",
    "# return=-22.700]\n",
    "# Iteration 9: 100%|██████████| 50/50 [00:00<00:00, 4705.19it/s, episode=500,\n",
    "# return=-61.700]\n",
    "\n",
    "# Q-learning算法最终收敛得到的策略为：\n",
    "# ^ooo ovoo ovoo ^ooo ^ooo ovoo ooo> ^ooo ^ooo ooo> ooo> ovoo\n",
    "# ooo> ooo> ooo> ooo> ooo> ooo> ^ooo ooo> ooo> ooo> ooo> ovoo\n",
    "# ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ooo> ovoo\n",
    "# ^ooo **** **** **** **** **** **** **** **** **** **** EEEE"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "第5章-时序差分算法.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
